using System.Transactions;
using OracleInternal.Common;

namespace OracleInternal.MTS
{
	internal class MTSProxyPool
	{
		private class MTSTxnRMs : SyncDictionary<string, MTSTxnRM>
		{
		}

		private class MTSProxies : SyncDictionary<string, MTSProxy>
		{
		}

		private static MTSProxies s_dbProxies;

		private static object s_lock;

		static MTSProxyPool()
		{
			s_dbProxies = new MTSProxies();
			s_lock = new object();
		}

		internal static MTSTxnRM GetRM(bool bIsCCP, string easyConnectName, string serviceName, string pdbName, Transaction txn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.MTSProxyPool, OracleTraceFuncName.GetRM, "Getting RM for Server ID = " + easyConnectName + " Txn Local ID = " + txn.TransactionInformation.LocalIdentifier);
			}
			string empty = string.Empty;
			empty = ((!string.IsNullOrEmpty(serviceName)) ? $"{easyConnectName}.{(string.IsNullOrEmpty(serviceName) ? string.Empty : serviceName)}" : $"{easyConnectName}.{string.Empty}");
			MTSTxnRM mTSTxnRM = null;
			try
			{
				MTSProxy mTSProxy = null;
				if ((mTSProxy = s_dbProxies[empty]) == null)
				{
					lock (s_lock)
					{
						if ((mTSProxy = s_dbProxies[empty]) == null)
						{
							if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4608, OracleTraceClassName.MTSProxyPool, OracleTraceFuncName.GetRM, "Creating MTSProxy for Server ID = " + empty + " Txn Local ID = " + txn.TransactionInformation.LocalIdentifier);
							}
							mTSProxy = new MTSProxy(empty);
							s_dbProxies[empty] = mTSProxy;
						}
						else
						{
							mTSProxy = s_dbProxies[empty];
						}
					}
				}
				mTSTxnRM = mTSProxy.GetRM(bIsCCP, serviceName, pdbName, txn);
				return mTSTxnRM;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4608, OracleTraceClassName.MTSProxyPool, OracleTraceFuncName.GetRM, "Getting TxnRM = " + ((mTSTxnRM != null) ? mTSTxnRM.m_RMGuid.ToString() : "null") + " for Server ID = " + empty + " Txn Local ID = " + txn.TransactionInformation.LocalIdentifier);
				}
			}
		}

		internal static void ReleaseRM(bool bIsCCP, string dataSource, Transaction txn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.MTSProxyPool, OracleTraceFuncName.ReleaseRM);
			}
			try
			{
				MTSProxy mTSProxy = null;
				if ((mTSProxy = s_dbProxies[dataSource]) != null)
				{
					mTSProxy.RemoveRM(bIsCCP, txn.TransactionInformation.LocalIdentifier);
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate_NoTrace)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4608, OracleTraceClassName.MTSProxyPool, OracleTraceFuncName.ReleaseRM);
				}
			}
		}
	}
}
